#include "DM_Raster_GDAL.h"
#include "..\include\NativeDataMappingAPI.h"
#include "UdxDataSchemaApi.h"
#include "UdxDataApi.h"

namespace NGIS
{
	namespace DataMapping
	{

		void IterateChildNodes(IUdxNodeSchema* pSNode, IUdxNode* pDNode)
		{
			if (pSNode==NULL) return;
			int count = pSNode->getChildNodeCount();
			if (count ==0) return;
			for (int i=0; i<count; i++)
			{
				IUdxNodeSchema* tempSNode = pSNode->getChildNode(i);
				const char* name = tempSNode->getName();
				ESchemaNodeType pSType = tempSNode->getDescription()->getKernelType();
				EKernelType pDType = getKernelTypeBySchema(pSType);
				IUdxNode* tempDNode = pDNode->addChildNode(name, pDType);
				IterateChildNodes(tempSNode, tempDNode);
			}
		}

		bool constructNode(IUdxNodeSchema* pSNode, IUdxNode* pDNode)
		{
			if (pDNode->getKernel()->getType() == EKernelType::EKT_NODE &&
				pSNode->getDescription()->getKernelType() != ESchemaNodeType::EDTKT_NODE &&
				pDNode->getChildNodeCount() == 0)
			{
				const char* node_name = pSNode->getName();
				ESchemaNodeType pSType = pSNode->getDescription()->getKernelType();
				EKernelType pDType = getKernelTypeBySchema(pSType);
				IUdxNode* tempDNode = pDNode->addChildNode(node_name, pDType);
			}
			for (int i=0; i<pSNode->getChildNodeCount(); i++)
			{
				IUdxNodeSchema* tempSNode = pSNode->getChildNode(i);
				const char* name = tempSNode->getName();
				ESchemaNodeType pSType = tempSNode->getDescription()->getKernelType();
				EKernelType pDType = getKernelTypeBySchema(pSType);
				IUdxNode* tempDNode = pDNode->addChildNode(name, pDType);
				IterateChildNodes(tempSNode, tempDNode);
			}
			return false;
		}

		extern "C" NATIVEDATAMAPPING_API EKernelType NATIVEDATAMAPPING_CALLCONV
			getKernelTypeBySchema(ESchemaNodeType pSType)
		{
			if (pSType == ESchemaNodeType::EDTKT_INT)
				return EKT_INT;
			else if (pSType == ESchemaNodeType::EDTKT_REAL)
				return EKT_REAL;
			else if (pSType == ESchemaNodeType::EDTKT_STRING)
				return EKT_STRING;
			else if (pSType == ESchemaNodeType::EDTKT_VECTOR2)
				return EKT_VECTOR2;
			else if (pSType == ESchemaNodeType::EDTKT_VECTOR3)
				return EKT_VECTOR3;
			else if (pSType == ESchemaNodeType::EDTKT_VECTOR4)
				return EKT_VECTOR4;
			else if (pSType == (ESchemaNodeType::EDTKT_INT | ESchemaNodeType::EDTKT_LIST))
				return EKT_INT_LIST;
			else if (pSType == (ESchemaNodeType::EDTKT_REAL | ESchemaNodeType::EDTKT_LIST))
				return EKT_REAL_LIST;
			else if (pSType == (ESchemaNodeType::EDTKT_STRING | ESchemaNodeType::EDTKT_LIST))
				return EKT_STRING_LIST;
			else if (pSType == (ESchemaNodeType::EDTKT_VECTOR2 | ESchemaNodeType::EDTKT_LIST))
				return EKT_VECTOR2_LIST;
			else if (pSType == (ESchemaNodeType::EDTKT_VECTOR3 | ESchemaNodeType::EDTKT_LIST))
				return EKT_VECTOR3_LIST;
			else if (pSType == (ESchemaNodeType::EDTKT_VECTOR4 | ESchemaNodeType::EDTKT_LIST))
				return EKT_VECTOR4_LIST;
			else if (pSType == ESchemaNodeType::EDTKT_NODE)
				return EKT_NODE;
			else if (pSType == ESchemaNodeType::EDTKT_LIST)
				return EKT_LIST;
			else if (pSType == ESchemaNodeType::EDTKT_MAP)
				return EKT_MAP;
			else if (pSType == ESchemaNodeType::EDTKT_TABLE)
				return EKT_TABLE;
			return EKT_COUNT;
		}

		extern "C" NATIVEDATAMAPPING_API bool NATIVEDATAMAPPING_CALLCONV
			ConstructDataFrame(IUdxNodeSchema* pSNode, IUdxNode* pDNode)
		{
			return constructNode(pSNode, pDNode);
		}

		extern "C" NATIVEDATAMAPPING_API IDataMappingHandle* NATIVEDATAMAPPING_CALLCONV 
			createGeneralRasterHandle()
		{
			DM_Raster_GADL* pRasterGDALHandle = new DM_Raster_GADL();
			return pRasterGDALHandle;
		}

	}
}